// ApiService.kt
package com.mxun.winefox.network

import android.content.Context
import android.media.MediaPlayer
import android.util.Log
import android.widget.Toast
import com.fasterxml.jackson.databind.ObjectMapper
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import okhttp3.*
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.RequestBody.Companion.toRequestBody
import org.json.JSONArray
import org.json.JSONObject
import org.msgpack.jackson.dataformat.MessagePackFactory
import java.io.File
import java.io.FileOutputStream
import java.security.MessageDigest
import java.util.concurrent.TimeUnit

object ApiService {
    private const val DEEPSEEK_API_KEY = "Bearer sk-3b45800700154f97a3cb2a0912ec0778"
    private const val FISH_AUDIO_API_KEY = "773c0f777a9e4cce9ae7e28c92688915"
    private const val CACHE_DIR_NAME = "tts_cache"

    // 生成唯一的缓存文件名
    private fun generateCacheKey(text: String, modelId: String): String {
        val input = "$text|$modelId"
        val md = MessageDigest.getInstance("MD5")
        val digest = md.digest(input.toByteArray())
        return digest.fold("") { str, it -> str + "%02x".format(it) } + ".mp3"
    }

    // 获取缓存文件
    private fun getCacheFile(context: Context, text: String, modelId: String): File {
        val cacheDir = File(context.cacheDir, CACHE_DIR_NAME)
        if (!cacheDir.exists()) cacheDir.mkdirs()
        return File(cacheDir, generateCacheKey(text, modelId))
    }

    // 清除特定文本的缓存
    fun clearCacheForText(context: Context, text: String, modelId: String) {
        val cacheFile = getCacheFile(context, text, modelId)
        if (cacheFile.exists()) {
            cacheFile.delete()
        }
    }

    // 清除所有缓存
    fun clearAllCache(context: Context) {
        val cacheDir = File(context.cacheDir, CACHE_DIR_NAME)
        if (cacheDir.exists()) {
            cacheDir.deleteRecursively()
        }
    }

    // Chat请求
    suspend fun fetchDeepSeekResponse(message: String, persona: String): String = withContext(Dispatchers.IO) {
        val client = OkHttpClient.Builder()
            .connectTimeout(30, TimeUnit.SECONDS)
            .readTimeout(60, TimeUnit.SECONDS)
            .build()

        val body = JSONObject().apply {
            put("model", "deepseek-chat")
            put("messages", JSONArray()
                .put(JSONObject().put("role", "system").put("content", persona))
                .put(JSONObject().put("role", "user").put("content", message))
            )
            put("max_tokens", 2000)
            put("temperature", 0.7)
            put("stream", false)
        }.toString().toRequestBody("application/json; charset=utf-8".toMediaType())

        val request = Request.Builder()
            .url("https://api.deepseek.com/chat/completions")
            .post(body)
            .addHeader("Authorization", DEEPSEEK_API_KEY)
            .addHeader("Content-Type", "application/json")
            .build()

        val response = client.newCall(request).execute()

        if (!response.isSuccessful) {
            throw Exception("API error: ${response.code} - ${response.body?.string()}")
        }

        val responseBody = response.body?.string() ?: throw Exception("Empty response")
        val jsonResponse = JSONObject(responseBody)
        val choices = jsonResponse.getJSONArray("choices")

        if (choices.length() > 0) {
            return@withContext choices
                .getJSONObject(0)
                .getJSONObject("message")
                .getString("content")
        }


        throw Exception("No valid response in API result")
    }

    // TTS播放函数
    suspend fun playTTS(
        context: Context,
        text: String,
        player: MediaPlayer,
        modelId: String,
        onStart: () -> Unit,
        onComplete: () -> Unit,
        forceRefresh: Boolean = false
    ): Boolean = withContext(Dispatchers.IO) {
        try {
            val cacheFile = getCacheFile(context, text, modelId)
            val hasCache = cacheFile.exists() && !forceRefresh

            if (!hasCache) {
                if (forceRefresh || !cacheFile.exists()) {
                    val requestMap = mapOf(
                        "text" to text,
                        "chunk_length" to 200,
                        "format" to "mp3",
                        "mp3_bitrate" to 128,
                        "normalize" to false,
                        "latency" to "normal",
                        "reference_id" to modelId,
                        "temperature" to 0.7,
                        "top_p" to 0.7
                    )

                    val mapper = ObjectMapper(MessagePackFactory())
                    val packedBody = mapper.writeValueAsBytes(requestMap)

                    val request = Request.Builder()
                        .url("https://api.fish.audio/v1/tts")
                        .post(packedBody.toRequestBody("application/msgpack".toMediaType()))
                        .addHeader("Authorization", "Bearer $FISH_AUDIO_API_KEY")
                        .addHeader("model", "s1")  // 确保使用S1模型
                        .build()

                    val client = OkHttpClient.Builder()
                        .connectTimeout(30, TimeUnit.SECONDS)
                        .readTimeout(60, TimeUnit.SECONDS)
                        .writeTimeout(30, TimeUnit.SECONDS)
                        .build()

                    val response = client.newCall(request).execute()

                    if (!response.isSuccessful) {
                        throw Exception("TTS API error: ${response.code} - ${response.body?.string()}")
                    }

                    response.body?.byteStream()?.use { input ->
                        FileOutputStream(cacheFile).use { output ->
                            input.copyTo(output)
                        }
                    }
                }
            }

            withContext(Dispatchers.Main) {
                player.reset()
                player.setDataSource(cacheFile.absolutePath)
                player.prepareAsync()
                player.setOnPreparedListener {
                    onStart()
                    it.start()
                }
                player.setOnCompletionListener {
                    onComplete()
                }
                player.setOnErrorListener { _, what, extra ->
                    onComplete()
                    Log.e("TTS_ERROR", "播放错误: $what, $extra")
                    false
                }
            }
            return@withContext hasCache

        } catch (e: Exception) {
            withContext(Dispatchers.Main) {
                onComplete()
                Log.e("TTS_ERROR", "TTS失败", e)
                Toast.makeText(context, "TTS失败: ${e.message}", Toast.LENGTH_SHORT).show()
            }
            return@withContext false
        }
    }
}